﻿namespace com.oakwoodsys.ConsultantCare
{
    using System;
    using System.Collections.Generic;

    using com.oakwoodsys.ConsultantCareDao;
    using com.oakwoodsys.Extensions.SharePointExtensions;
    using com.oakwoodsys.Extensions.StringExtensions;
    using com.oakwoodsys.Extensions.SymbolExtensions;
    using com.oakwoodsys.SharePoint;

    using Microsoft.SharePoint;

    /// <summary>
    /// List Item Events
    /// </summary>
    public class ConsultantItemEventReceiver : SPItemEventReceiver
    {
        #region Fields

        string _columnName_Recruiter;

        #endregion Fields

        #region Enumerations

        enum Assoc
        {
            Consultant,
            Permanent
        }

        #endregion Enumerations

        #region Properties

        string columnName_Recruiter
        {
            get
            {
                if ( string.IsNullOrEmpty( _columnName_Recruiter ) )
                {
                    Consultant c = null;
                    _columnName_Recruiter = Item.GetColumnName<Consultant>( c.GetPropertySymbol( o => o.RecruiterId ) );
                }
                return _columnName_Recruiter;
            }
        }

        #endregion Properties

        #region Methods

        /// <summary>
        /// An item was added.
        /// </summary>
        public override void ItemAdded( SPItemEventProperties properties )
        {
            if ( properties.ListItem.ContentType.Name.Equals( Consultant.GetContentTypeName<Consultant>( ) ) )
            {
                Consultant consultant = getConsultant( properties );
                if ( consultant != null && consultant.Active.HasValue && consultant.Active.Value )
                {
                    List<ConsultantCareActivity> activities = getActivities( properties, ( consultant.Type.HasValue && consultant.Type.Value == ConsultantCareDao.Type.Consultant ) ? Assoc.Consultant : Assoc.Permanent );
                    CalendarEventCreator creator = new CalendarEventCreator( properties.WebUrl );
                    creator.AddCalendarEvents( consultant, activities );
                }
            }
        }

        /// <summary>
        /// An item is being added.
        /// </summary>
        public override void ItemAdding( SPItemEventProperties properties )
        {
            Recruiter recruiter = getRecruiter( properties );
            if ( recruiter == null )
            {
                properties.Status = SPEventReceiverStatus.CancelWithRedirectUrl;
                properties.RedirectUrl = MessageHandler.GetRedirectUrl( MessageHandler.Message.Consultant.ConsultantNotAddedRecruiterNotFound );
            }
            else
            {
                SharePointUri recruiterCalendarUri = new SharePointUri( recruiter.CalendarPathUrl );
                if ( !recruiterCalendarUri.ListFound )
                {
                    properties.Status = SPEventReceiverStatus.CancelWithRedirectUrl;
                    properties.RedirectUrl = MessageHandler.GetRedirectUrl( MessageHandler.Message.Consultant.ConsultantNotAddedCalendarNotFound );
                }
                else
                {
                    ConsultantCareConfigurationDao dao = new ConsultantCareConfigurationDao( properties.WebUrl );
                    ConsultantCareConfiguration configuration = dao.Get( );
                    SharePointUri masterCalendarUri = new SharePointUri( configuration.CalendarPathUrl );
                    if ( !masterCalendarUri.ListFound )
                    {
                        properties.Status = SPEventReceiverStatus.CancelWithRedirectUrl;
                        properties.RedirectUrl = MessageHandler.GetRedirectUrl( MessageHandler.Message.Consultant.ConsultantNotAddedMasterCalendarNotFound );
                    }
                }
            }
        }

        /// <summary>
        /// An item is being deleted.
        /// </summary>
        public override void ItemDeleting( SPItemEventProperties properties )
        {
            if ( properties.ListItem.ContentType.Name.Equals( Consultant.GetContentTypeName<Consultant>( ) ) )
            {
                DeletionDao dao = new DeletionDao( properties.WebUrl );
                dao.Add( "C", properties.ListItem.UniqueId );

                //CalendarEventCreator creator = new CalendarEventCreator( properties.WebUrl );
                //creator.RemoveCalendarEventsByConsultant( properties.ListItem.UniqueId );
            }
        }

        /// <summary>
        /// An item was updated.
        /// </summary>
        public override void ItemUpdated( SPItemEventProperties properties )
        {
            if ( properties.ListItem.ContentType.Name.Equals( Consultant.GetContentTypeName<Consultant>( ) ) )
            {
                Consultant consultant = getConsultant( properties );
                // if valid consultant
                if ( consultant != null )
                {
                    // remove calendar events associated with consultant
                    CalendarEventCreator creator = new CalendarEventCreator( properties.WebUrl );
                    creator.RemoveCalendarEvents( consultant );

                    // if consultant is active
                    if ( consultant.Active.HasValue && consultant.Active.Value )
                    {
                        // get appropriate activities based upon hire type (ie. consultant, permanent)
                        List<ConsultantCareActivity> activities = getActivities( properties, ( consultant.Type.HasValue && consultant.Type.Value == ConsultantCareDao.Type.Consultant ) ? Assoc.Consultant : Assoc.Permanent );
                        // add calendar events
                        creator.AddCalendarEvents( consultant, activities );
                    }
                }
            }
        }

        /// <summary>
        /// An item is being updated.
        /// </summary>
        public override void ItemUpdating( SPItemEventProperties properties )
        {
            if ( properties.ListItem.ContentType.Name.Equals( Consultant.GetContentTypeName<Consultant>( ) ) )
            {
                Consultant consultant = getConsultant( properties );
                Recruiter recruiter = getRecruiter( properties );
                if ( recruiter == null )
                {
                    properties.Status = SPEventReceiverStatus.CancelWithRedirectUrl;
                    properties.RedirectUrl = MessageHandler.GetRedirectUrl( MessageHandler.Message.Consultant.ConsultantNotUpdatedRecruiterNotFound, consultant.Title, consultant.Recruiter );
                }
                else
                {
                    SharePointUri recruiterCalendarUri = new SharePointUri( recruiter.CalendarPathUrl );
                    if ( !recruiterCalendarUri.ListFound )
                    {
                        properties.Status = SPEventReceiverStatus.CancelWithRedirectUrl;
                        properties.RedirectUrl = MessageHandler.GetRedirectUrl( MessageHandler.Message.Consultant.ConsultantNotUpdatedCalendarNotFound, consultant.Title, consultant.Recruiter );
                    }
                    else
                    {
                        ConsultantCareConfigurationDao dao = new ConsultantCareConfigurationDao( properties.WebUrl );
                        ConsultantCareConfiguration configuration = dao.Get( );
                        SharePointUri masterCalendarUri = new SharePointUri( configuration.CalendarPathUrl );
                        if ( !masterCalendarUri.ListFound )
                        {
                            properties.Status = SPEventReceiverStatus.CancelWithRedirectUrl;
                            properties.RedirectUrl = MessageHandler.GetRedirectUrl( MessageHandler.Message.Consultant.ConsultantNotUpdatedMasterCalendarNotFound, consultant.Title );
                        }
                    }
                }
            }
        }

        List<ConsultantCareActivity> getActivities( SPItemEventProperties properties, Assoc associated )
        {
            ConsultantCareActivityDao dao = new ConsultantCareActivityDao( properties.WebUrl );
            List<ConsultantCareActivity> activities = associated == Assoc.Consultant ? dao.GetAllConsultantAssociated( ) : dao.GetAllPermanentAssociated( );
            return activities;
        }

        Consultant getConsultant( SPItemEventProperties properties )
        {
            ConsultantDao dao = new ConsultantDao( properties.WebUrl );
            return dao.Get( properties.ListItem.UniqueId );
        }

        Recruiter getRecruiter( SPItemEventProperties properties )
        {
            Recruiter recruiter = null;
            try
            {
                string s = ( string ) properties.AfterProperties[ columnName_Recruiter ];
                int? id = s.ToNullableInt32( );
                if ( id.HasValue )
                {
                    RecruiterDao dao = new RecruiterDao( properties.WebUrl );
                    recruiter = dao.GetByRecruiter( id.Value );
                }
            }
            catch
            {
                recruiter = null;
            }
            return recruiter;
        }

        #endregion Methods
    }
}